/*
 * CONTROL ROBOT 5
 * 
 * */

#include "../application/Robot5API.h"
#include "../logger/logger.h"
#include "../common/StringUtils.h"
#include "../middleware/MiddlewareCommon.h"
#include "../common/Argv.h"
using namespace std;

/*
 * Robot 5.
 *
 * EL flujo de operación es el siguiente:
 *
 *	Repetir:
 * 		Si no tiene pedidos de ningún tipo, espera.
 * 		Si no:
 * 			Se fija los pedidos en este orden:
 *									 	- almacen de piezas
 *									 	- llevar canastos
 *									  	- mover cintas
 *									  	- pedidos de produccion
 *		Atiende cada uno de los pedidos y vuelve al comienzo del ciclo
 *
 */


int main(int argc, char* argv[]) {

	CLogger::create("Robot 5");
	CLogger::setLevel(LogLevelEnum::TRACE);
	CLogger::log("Empieza a simular.", LogLevelEnum::INFO);	

	int tipoProducto=0;
	int cantidadFaltante=0;
	bool cintaLibre1=true;
	bool cintaLibre2=true;

	Argv args(argv);
	if (args.getArgc() < 2) {
		CLogger::log("Parámetros inválidos. Uso: ./robot5 hostName", LogLevelEnum::FATAL);
		exit(1);
	}

	application::Robot5API api(args.getArg(1));

	if (DSM_ENABLED) {
		DSMManager::inicializar( args.getArg(1) );
	}

	while(true){
		//lee la memoria de pedidos
		PendientesRobot5 eventos=api.verListaDeEventos();
		bool nadaParaHacer=true;

		CLogger::log("cantidad Faltante: "+ StringUtils::NumberToString(cantidadFaltante), LogLevelEnum::INFO);
		if(cintaLibre1)CLogger::log("Cinta1 libre", LogLevelEnum::INFO);
		else CLogger::log("Cinta1 ocupada", LogLevelEnum::INFO);
		if(cintaLibre2)CLogger::log("Cinta2 libre", LogLevelEnum::INFO);
		else CLogger::log("Cinta2 ocupada", LogLevelEnum::INFO);

		CLogger::log("Recepciones de Canastos: " + StringUtils::NumberToString(eventos.contador[R5_PEDIDOS_PENDIENTES_RECEPCION_CANASTOS]), LogLevelEnum::INFO);
		CLogger::log("Pedidos de Canastos: " + StringUtils::NumberToString(eventos.contador[R5_PEDIDOS_PENDIENTES_CANASTOS]), LogLevelEnum::INFO);
		CLogger::log("Pedidos de Cinta: " + StringUtils::NumberToString(eventos.contador[R5_PEDIDOS_PENDIENTES_CINTAS]), LogLevelEnum::INFO);
		CLogger::log("Pedidos de Produccion: " + StringUtils::NumberToString(eventos.contador[R5_PEDIDOS_PENDIENTES_PROD]), LogLevelEnum::INFO);


		//***  ALMACEN DE PIEZAS ***///
		if(eventos.contador[R5_PEDIDOS_PENDIENTES_RECEPCION_CANASTOS]>0){//esto lo envia el almacen
			CLogger::log("Recibiendo canasto del ADP", LogLevelEnum::INFO);
			Canasto canasto=api.buscarCanastoDeADP();
			api.darCanastoAlAGV(canasto.idAGV,canasto);
			nadaParaHacer=false;


			//***PEDIDOS DE CANASTOS***//
		}else if (eventos.contador[R5_PEDIDOS_PENDIENTES_CANASTOS]>0){ //esto lo manda el avg
			CLogger::log("Recibiendo pedido de canasto del AGV", LogLevelEnum::INFO);
			PedidoCanasto peidoCan=api.verPedidoDeCanasto();
			cout<<"Pedir canasto al ADP, Para el AGV " << peidoCan.idAgv << ",con TipoPieza "<< peidoCan.idPieza << endl;
			//api.pedirCanastoAlADP(peidoCan);este es el original
			//empieza el mock
			Canasto canasto;
			canasto.idPieza= peidoCan.idPieza;
			canasto.cantidad=500;//tirar un random aca
			canasto.idAGV=peidoCan.idAgv;   
			cout<<"Dar canasto al AGV " << peidoCan.idAgv << ",con TipoPieza "<< peidoCan.idPieza << endl;
			api.darCanastoAlAGV(canasto.idAGV,canasto);
			nadaParaHacer=false;

			//***CINTAS TRANSPORTADORAS
		}else if (eventos.contador[R5_PEDIDOS_PENDIENTES_CINTAS]>0){//lo manda el r11
			CLogger::log("Recibiendo pedido de cinta", LogLevelEnum::INFO);
			PedidoCintas pedidoCinta=api.verPedidoDeCinta();
			if(pedidoCinta.id==1) cintaLibre1=true; //marca la cinta correspondiente como libre para otro producto
			else cintaLibre2=true;
			nadaParaHacer=false;

			//***REMANENTE DE PRODUCCION*****//
		}else if(cantidadFaltante > 0 && (cintaLibre1 || cintaLibre2)){
			api.liberarPendientes();

			//elegir cinta
			int numeroDeCinta=0;
			if(cintaLibre1 && cintaLibre2){
				if(api.cantidadProductosEnCinta(1)<= api.cantidadProductosEnCinta(2)) numeroDeCinta=1;
				else numeroDeCinta=2;
			}else if(cintaLibre1){
				numeroDeCinta=1;
			}else{
				numeroDeCinta=2;
			}
			CLogger::log("Elijo cinta " + StringUtils::itos(numeroDeCinta), LogLevelEnum::INFO);

			//genero magicamente los gabinetes
			Producto prod;
			prod.productoId=4;//que id?
			prod.tipo=tipoProducto;
			prod.estado=PRODUCTO_EN_PRODUCCION;
			bool libre=api.ponerProductoEnCinta(numeroDeCinta,prod);

			if (numeroDeCinta==1){
				cintaLibre1=libre;
			}else{
				cintaLibre2=libre;
			}
			cantidadFaltante--;
			nadaParaHacer=false;

			//***PEDIDOS DE PRODUCCION***//
		}else if (eventos.contador[R5_PEDIDOS_PENDIENTES_PROD] > 0 && cantidadFaltante == 0){
			CLogger::log("Recibiendo pedido de produccion", LogLevelEnum::INFO);
			PedidoProduccion pedidoDeProd=api.verPedidoDeProduccion();
			tipoProducto=pedidoDeProd.tipoProducto;
			cantidadFaltante=pedidoDeProd.cantidad;
			nadaParaHacer=false;
			CLogger::log("Tipo "+ StringUtils::itos(tipoProducto) + " cantidad " + StringUtils::itos(cantidadFaltante) , LogLevelEnum::INFO);

		}

		//**NADA PARA HACER,A LA CAMAAAA!!!!**///
		if(nadaParaHacer){//no tiene pedidos por lo que se pone a dormir
			CLogger::log("Nada para hacer...Durmiendo...", LogLevelEnum::INFO);
			api.noHacerNada();
			CLogger::log("WakeUp!!! Nuevo evento disponible!", LogLevelEnum::INFO);
		}

	}
}
